import {Injectable} from '@nestjs/common';
import {PrismaService} from '@/common/service/prisma/prisma.service';
import {Response} from 'express';
import {exportTable} from '@/common/utils';
import {CreateRentalLeaseDto, QueryRentalLeaseDto, UpdateRentalLeaseDto,} from '../dto/index';
import {Prisma} from '@prismaClient';
import {isEmpty, isNotEmpty} from 'class-validator';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';

@Injectable()
export class RentalLeaseService {
  constructor(
      private prisma: PrismaService,
      @InjectQueue('autoCheckIfItExpires') private expireQueue: Queue,
  ) {}

  /**@description 查询房源表所有 */
  async getHouseList() {
    return this.prisma.rentalHouse.findMany({
      where: { delFlag: '1' },
    });
  }

  /**@description 查询租客表所有 */
  async getUserList() {
    return this.prisma.sysUser.findMany({
      where: {
        status: '1',
        roles: {
          some: {
            role: {
              roleKey: 'common', // 角色的标识为 common
            },
          },
        },
      },
    });
  }

  /**@description 查询租赁关系表所有 */
  async selectLeaseAll() {
    return this.prisma.rentalLease.findMany();
  }

  /**@description 分页查询租赁关系表列表 */
  async selectLeaseList(q: QueryRentalLeaseDto) {
    let queryCondition: Prisma.RentalLeaseWhereInput = {};
    if (isNotEmpty(q['tenantId'])) {
      queryCondition.tenantId = {
        equals: q.tenantId,
      };
    }
    if (isNotEmpty(q['leaseStatus'])) {
      queryCondition.leaseStatus = {
        equals: q.leaseStatus,
      };
    }
    if (
      isNotEmpty(q.params.beginStartDate) &&
      isNotEmpty(q.params.endStartDate)
    ) {
      queryCondition.startDate = {
        lte: q.params.endStartDate,
        gte: q.params.beginStartDate,
      };
    }
    if (isNotEmpty(q.params.beginEndDate) && isNotEmpty(q.params.endEndDate)) {
      queryCondition.endDate = {
        lte: q.params.endEndDate,
        gte: q.params.beginEndDate,
      };
    }
    return {
      rows: await this.prisma.rentalLease.findMany({
        skip: (q.pageNum - 1) * q.pageSize,
        take: q.pageSize,
        where: queryCondition,
      }),
      total: await this.prisma.rentalLease.count({
        where: queryCondition,
      }),
    };
  }

  /**@description 查询租赁关系表详情 */
  async selectLeaseById(id: number) {
    return  this.prisma.rentalLease.findUnique({
      where: {
        id,
      },
    })
  }

  /**@description 新增租赁关系表 */
  async addLease(rentalLease: CreateRentalLeaseDto) {
    if (isEmpty(rentalLease['tenantId'])) {
      delete rentalLease['tenantId'];
    }
    if (isEmpty(rentalLease['houseId'])) {
      delete rentalLease['houseId'];
    }
    if (isEmpty(rentalLease['leaseStatus'])) {
      delete rentalLease['leaseStatus'];
    }
    if (isEmpty(rentalLease['delFlag'])) {
      delete rentalLease['delFlag'];
    }
    if (isEmpty(rentalLease['createTime'])) {
      delete rentalLease['createTime'];
    }
    if (isEmpty(rentalLease['updateTime'])) {
      delete rentalLease['updateTime'];
    }
    if (isEmpty(rentalLease['startDate'])) {
      delete rentalLease['startDate'];
    }
    if (isEmpty(rentalLease['endDate'])) {
      delete rentalLease['endDate'];
    }
    const result = { msg: '', data: null, code: 400 };
    const user = await this.prisma.sysUser.findUnique({
      where: {
        status: '1',
        userId: rentalLease['tenantId'],
        roles: {
          some: {
            role: {
              roleKey: 'common', // 查找角色标识为 common 的记录
            },
          },
        },
      },
    });
    const house = await this.prisma.rentalHouse.findUnique({
      where: { id: rentalLease['houseId'], status: '1', delFlag: '1' },
    });
    if (!user) {
      result.msg = '此租客不存在或已被封禁';
    }
    if (!house) {
      result.msg = '此房源不存在或已被出售下架';
    } else {
      result.code = 200;
      result.msg = '添加成功';
      const delay = new Date(rentalLease.endDate).getTime() - Date.now();
      const [createdRentalLease] = await this.prisma.$transaction([
        this.prisma.rentalLease.create({
          data: { ...rentalLease, leaseStatus: delay > 0 ? '0' : '1' },
        }),
        this.prisma.rentalHouse.update({
          where: { id: rentalLease['houseId'] },
          data: { status: delay > 0 ? '0' : '1' },
        })
      ])
      result.data = createdRentalLease;
      if(delay > 0){
        await this.expireQueue.add(
            {rentalLeaseId: result.data.id},
            {delay}
        )
      }else {
        await this.expireQueue.add({ rentalLeaseId: result.data.id });
      }
    }
    return result;
  }

  /**@description 修改租赁关系表 */
  async updateLease(rentalLease: UpdateRentalLeaseDto) {
    if (isEmpty(rentalLease['tenantId'])) {
      delete rentalLease['tenantId'];
    }
    if (isEmpty(rentalLease['houseId'])) {
      delete rentalLease['houseId'];
    }
    if (isEmpty(rentalLease['leaseStatus'])) {
      delete rentalLease['leaseStatus'];
    }
    if (isEmpty(rentalLease['delFlag'])) {
      delete rentalLease['delFlag'];
    }
    if (isEmpty(rentalLease['createTime'])) {
      delete rentalLease['createTime'];
    }
    if (isEmpty(rentalLease['updateTime'])) {
      delete rentalLease['updateTime'];
    }
    if (isEmpty(rentalLease['startDate'])) {
      delete rentalLease['startDate'];
    }
    if (isEmpty(rentalLease['endDate'])) {
      delete rentalLease['endDate'];
    }
    if (new Date(rentalLease['endDate']) > new Date()) {
      rentalLease['leaseStatus'] = '0'
      const delay = new Date(rentalLease.endDate).getTime() - Date.now();
      if(delay > 0){
        await this.expireQueue.add(
            {rentalLeaseId: rentalLease['id']},
            {delay}
        )
      }else {
        await this.expireQueue.add({ rentalLeaseId: rentalLease['id'] });
      }
    }
    else rentalLease['leaseStatus'] = '1'
    const [ result ] = await this.prisma.$transaction([
      this.prisma.rentalLease.update({
        where: {
          id: rentalLease.id,
        },
        data: rentalLease,
      }),
        this.prisma.rentalHouse.update({
          where: {
            id: rentalLease['houseId']
          },
          data: { status: rentalLease['leaseStatus'] }
        })
    ])
    return result;
  }

  /**@description 批量删除租赁关系表 */
  async deleteLeaseByIds(ids: number[]) {
    const result = { count : 1, message: '', data: null }
    const leases = await this.prisma.rentalLease.findMany({
      where: {
        id: {
          in: ids,
        },
      },
      select: {
        houseId: true,
        leaseStatus: true,
      },
    })
    if(leases.some(v=>v.leaseStatus === '0')){
      result.count = 0
      result.message = '租赁状态未结束不能删除'
    }
    else {
      result.message = '删除成功'
      result.data = await this.prisma.$transaction([
        this.prisma.rentalLease.deleteMany({
          where: {
            id: {
              in: ids,
            },
          },
        }),
        ...leases.map(v =>
            this.prisma.rentalHouse.update({
              where: { id: v.houseId },
              data: { status: '1' },
            })
        ),
      ]);
    }
    return result;
  }

  /**@description 单个删除租赁关系表 */
  async deleteLeaseById(id: number) {
    const lease = await this.prisma.rentalLease.findUnique({ where: { id }, select: { houseId: true } })
    return this.prisma.$transaction([
      this.prisma.rentalLease.delete({where: {id}}),
      this.prisma.rentalHouse.update({
        where: {id: lease.houseId},
        data: {status: '1'},
      }),
    ]);
  }


  /**@description 导出租赁关系表所有数据为xlsx */
  async exportLease(res: Response) {
    let title = [
      '租赁ID',
      '租客ID',
      '房源ID',
      '租赁状态（0-已结束，1-进行中）',
      '删除标记（0-已删除，1-正常）',
      '创建时间',
      '更新时间',
      '开始日期',
      '结束日期',
    ];
    let data = (await this.prisma.rentalLease.findMany()).map((v) =>
      Object.values(v),
    );
    data.unshift(title);
    await exportTable(data, res);
  }
}
